package gae.colopl;

import gae.colopl.bean.User;
import gae.colopl.http.ColoplLoginException;
import gae.colopl.http.ColoplRequestException;
import gae.colopl.http.ColoplRequestManager;
import gae.colopl.http.bean.ItemWHData;
import gae.colopl.http.bean.LinkColony;
import gae.colopl.http.bean.LinkData;
import gae.colopl.http.user.Session;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.CacheFactory;
import javax.cache.CacheManager;

import com.google.appengine.api.memcache.jsr107cache.GCacheFactory;

public class CacheColoplServiceImpl extends AbstractColoplService 
                                    implements CacheColoplService {
    
    private Cache cache;
    
    
    
    public CacheColoplServiceImpl() {
        try {
            CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
            Map props = new HashMap();
            props.put(GCacheFactory.EXPIRATION_DELTA, 1800);
            cache = cacheFactory.createCache(props);
        } catch (CacheException e) {
            // FIXME
            e.printStackTrace();
        }
    }
    
    @Override
    public User getUserInfo(String username, String password) throws ColoplRequestException, ColoplLoginException {
        
        Session userSession = manager.requestLogin(username, password);
        
        User userInfo = new User();
        userInfo.setUsername(username);
        userInfo.setPassword(password);
        userInfo.setId(userSession.getId());
        userInfo.setUid(userSession.getUid());
        
        return userInfo;
    }
    
    @Override
    public void refresh(ColoplDataType type, String username, String password) throws ColoplRequestException {
        switch (type) {
        case WAREHOUSE:
            cache.remove(username + ".ItemWHData");
            break;
        case LINK:
            cache.remove(username + ".Near.LinkColonyData");
            cache.remove(username + ".Far.LinkColonyData");
            cache.remove(username + ".Friend.LinkColonyData");
        }
    }

    @Override
    protected List<ItemWHData> getWHItems(String username, String password) throws ColoplRequestException {
        List<ItemWHData> data = (List<ItemWHData>)cache.get(username + ".ItemWHData");
        if (data == null) {
            data = new ArrayList<ItemWHData>();
            ItemWHData wh = manager.requestItemWH(username, password, 0);
            int pageSize = Integer.valueOf(wh.getPageCount());
            for (int i = 0; i < pageSize; i++) {
                if (i != 0) {
                    wh = manager.requestItemWH(username, password, i);
                }
                data.add(wh);
            }
            cache.put(username + ".ItemWHData", data);
        }
        
        return data;
    }

    @Override
    protected List<LinkColony> getNearLinkColonies(String username,
            String password) throws ColoplRequestException {
        
        List<LinkColony> data = (List<LinkColony>)cache.get(username + ".Near.LinkColonyData");
        if (data == null) {
            LinkData ld = manager.requestLink(username, password);
            pushLinkData(username, ld);
            data = ld.getNearColony();
        }
        
        return data;
    }
    
    @Override
    protected List<LinkColony> getFarLinkColonies(String username,
            String password) throws ColoplRequestException {

        List<LinkColony> data = (List<LinkColony>)cache.get(username + ".Far.LinkColonyData");
        if (data == null) {
            LinkData ld = manager.requestLink(username, password);
            pushLinkData(username, ld);
            data = ld.getFarColony();
        }
        
        return data;
    }

    @Override
    protected List<LinkColony> getFriendLinkColonies(String username,
            String password) throws ColoplRequestException {

        List<LinkColony> data = (List<LinkColony>)cache.get(username + ".Friend.LinkColonyData");
        if (data == null) {
            LinkData ld = manager.requestLink(username, password);
            pushLinkData(username, ld);
            data = ld.getFriendColony();
        }
        
        return data;
    }
    
    private void pushLinkData(String username, LinkData data) {
        cache.put(username + ".Near.LinkColonyData", data.getNearColony());
        cache.put(username + ".Far.LinkColonyData", data.getFarColony());
        cache.put(username + ".Friend.LinkColonyData", data.getFriendColony());
    }

}
